/*
    工单完成后检查是否个案下的所有工单都已完成
    所有工单状态为"完成"后设置个案状态为"关闭"

其他工单：客户签名，设置服务完成时间；是否服务追踪不为空，工单完成；已回访不为空，个案关闭。
服务工单和保养工单：客户签名，设置服务完成时间，工单完成，个案关闭。

//安装工单：客户签名，设置服务完成时间，工单完成；上传附件，个案关闭。

1、代理及自产安装工单：当使用科室是否签名为true且安装报告纸质报告大于0时，获取服务完成时间，工单完成、个案关闭；

2、非代理安装工单：当安装报告纸质报告大于0时，获取服务完成时间，工单完成、个案关闭。

*/
public without sharing class WorkOrderHandle implements Triggers.Handler {


    //当服务工单完成时 判断当前仪器是否要反写到仪器上的返修标记(未标记且: 90天内有4个服务工单)
    public  void backToEquipment(Set<Id> equips ,Id serviceOrderId ){

        Map<String ,Decimal> eMap = new Map<String,Decimal>();
        for(Equipment__c e : [select Id,RepairInstrument__c,FromFlow__c  from Equipment__c where Id in: equips and RepairInstrument__c != true ]){
            eMap.put(e.Id,e.FromFlow__c);
        }
        System.debug('backToEquipment==>'+eMap);
        Datetime day90 = System.now().addDays(-90);
        List<Equipment__c> eqList = new List<Equipment__c>();

        for( AggregateResult arg :[select count(Id) total  , ServiceManufacture__c from  WorkOrder__c  where Install_Start_Datetime__c >=: day90 
            and Status__c = '完成' and ServiceManufacture__c in:eMap.keySet() and RecordTypeId =:serviceOrderId group by ServiceManufacture__c  ]){
            String eid =  String.valueOf(arg.get('ServiceManufacture__c'));
            if(Integer.valueOf(arg.get('total')) >=4 &&eMap.containsKey(eid) ){
                Decimal d = eMap.get(eid) > 0 ? 0 : 1 ;
                eqList.add(new Equipment__c(Id =eid ,RepairInstrument__c = true ,FromFlow__c = d  ));
            }
        }

        System.debug('backToEquipment==>'+equips);
        System.debug('backToEquipment==>'+eqList);
        update eqList;

    } 
    // 工单完成
    public void handle() {

        if(Trigger.isBefore && Trigger.isUpdate ){
            List<WorkOrder__c> newList = (List<WorkOrder__c>)Trigger.new;
            Id rt = Utils.getRecordTypeIdByDevNameAndObjName('RecordTypeTrackingRecordAfterTraining', 'WorkOrder__c');
            Id installrt = Utils.getRecordTypeIdByDevNameAndObjName('InstallationOrder', 'WorkOrder__c');
            Id nonagentInstallrt = Utils.getRecordTypeIdByDevNameAndObjName('NonAgentInstallationOrder', 'WorkOrder__c');
            
            for (WorkOrder__c wo  : newList) {

                if(wo.RecordTypeId == rt && wo.Status__c != '完成'   && wo.ProjectResults__c != null  ){

                     


                    wo.Status__c = '完成';
                    wo.Install_End_Datetime__c = System.now();

                }

                if(wo.RecordTypeId == installrt && wo.ReportNumber__c != null && wo.ReportNumber__c > 0 && wo.Signed_UsedDepartmen__c == true )wo.Status__c = '完成';
                if(wo.RecordTypeId == nonagentInstallrt && wo.ReportNumber__c != null && wo.ReportNumber__c > 0 )wo.Status__c = '完成';
                 if( (wo.RecordTypeId == nonagentInstallrt  ||  wo.RecordTypeId == installrt ) &&wo.LineType__c == '迈克血液流水线'  && wo.isAddKit__c == false ){

                        wo.addError('请点击添加成套件!');
                        return;
                    }


                //if(wo.Install_End_Datetime__c == null && (wo.RecordTypeId==installrt||wo.RecordTypeId == nonagentInstallrt) && wo.Status__c == '完成' )wo.Install_End_Datetime__c = System.now();

            }


        }
        if(Trigger.isAfter && Trigger.isUpdate){
            Id serviceOrderId  = Utils.getRecordTypeIdByDevNameAndObjName('ServiceOrder', 'WorkOrder__c');
            List<WorkOrder__c> newList = (List<WorkOrder__c>)Trigger.new;
            List<Case> clist = new List<Case>();
            Map<Id,WorkOrder__c> oldList =(Map<Id,WorkOrder__c>) trigger.oldMap;
            
            Map<String,WorkOrder__c> mapCase = new Map<String,WorkOrder__c>();
            
            Map<Id,Id>etoCase = new Map<Id,Id>();//服务仪器修改反写到服务请求
            Map<Id,String> recMap = new Map<Id,String>();
            for(RecordType r :[select Id,DeveloperName from RecordType where SobjectType = 'WorkOrder__c' ]){
                recMap.put(r.Id, r.DeveloperName);
            }


            Set<Id> equips = new Set<Id>();
            for (WorkOrder__c w : newList) {
                

                if (w.Status__c == '完成') {

                    //回写合同仪器的安装数量
                    if(oldList.get(w.Id).Status__c != '完成'){

                        List<WorkOrder__c> woL = [select Id,Case__r.InstallationApply__r.ContractEquipment__c from WorkOrder__c
                         where Id =:w.Id and RecordType.DeveloperName in ('InstallationOrder','NonAgentInstallationOrder')
                         and Case__r.InstallationApply__r.ContractEquipment__c != null ];
                         if(!woL.isEmpty())ContractCalcEquipmentUtil.installBackToContract(woL[0].Case__r.InstallationApply__r.ContractEquipment__c);
                         
                    }
                    if(oldList.get(w.Id).Status__c != '完成' && w.ServiceManufacture__c != null  ){
                        equips.add(w.ServiceManufacture__c);
                    }
                    if(String.isNotBlank(w.Case__c) && !mapCase.containsKey(w.Case__c)){
                        mapCase.put(w.Case__c,null);

                    }
                }
                ///如果服务仪器修改
                if(oldList.containsKey(w.Id)){
                	WorkOrder__c oldw = oldList.get(w.Id);
                    
                    if(recMap.get(w.RecordTypeId)!='InstallationOrder' && recMap.get(w.RecordTypeId)!='NonAgentInstallationOrder' && w.ServiceManufacture__c != oldw.ServiceManufacture__c){
                        //保存服务仪器 和对应的个案
                    	etoCase.put(w.Case__c,w.ServiceManufacture__c);
                    }
                }
                
            }
            if(equips.size() > 0)backToEquipment(equips,serviceOrderId);
            equips.clear();
            //如果有修改过的服务仪器 反写到服务请求 ,排除年度服务计划的服务请求
            if(etoCase.keySet().size() > 0){
                List<Case> ceList = [select ServiceManufacture__c from Case where Id in:etoCase.keySet() and RecordType.DeveloperName != 'ServicePlanCase' and RecordType.DeveloperName  != 'MaintenanceOrder'];
            	for(Case c :ceList){
                	c.ServiceManufacture__c = etoCase.get(c.Id);
                    c.IsUpdateWorkOrder__c = !c.IsUpdateWorkOrder__c ;
                }
                System.debug('改过的服务仪器'+ceList);
                update ceList;
            }
            List<WorkOrder__c> lockList = new List<WorkOrder__c>();

            if(mapCase.size() > 0){

               Set<String> rtSet = new Set<String>();
                rtSet.add('TeachingTraining');
                rtSet.add('Reagents');
                rtSet.add('clinicalpromotion');
                rtSet.add('InstrumentsTraining');
                rtSet.add('calibration');
                rtSet.add('MaintenanceOrder');
                rtSet.add('ProblemSolving');
                rtSet.add('InstallationOrder');
                rtSet.add('TechnicalTours');
                rtSet.add('ServiceOrder');
                rtSet.add('UsersReflect');
                rtSet.add('EvaluationTest');
                rtSet.add('SoftwareInstallationTraining');



                Set<String> woset = new Set<String>{'ServiceOrder','InstallationOrder','NonAgentInstallationOrder','Relocation','MaintenanceOrder','CalibrationEngineer','Upgrade'};
                //查询出个案下的所有工单，检查是否都已完成
                Map<Id,Boolean> cBMap = new Map<Id,Boolean>();
                List<WorkOrder__c> wList = [
                        SELECT Id,Status__c,Case__c,Signed_Engineer__c,Case__r.RecordType.DeveloperName ,Signed_UsedDepartmen__c,ReportNumber__c,Visit__c,RecordType.DeveloperName,case__r.IsUpdateWorkOrder__c
                        FROM WorkOrder__c 
                        WHERE Case__c IN : mapCase.keySet() and Case__r.Status != '关闭' ];

                Map<Id,List<WorkOrder__c>> cwMap = new Map<Id,List<WorkOrder__c>>();
                for (WorkOrder__c w : wList) {
                    List<WorkOrder__c> temp = new List<WorkOrder__c>();
                    if(cwMap.containsKey(w.Case__c)){
                        temp.addAll(cwMap.get(w.Case__c));
                    }
                    temp.add(w);
                    cwMap.put(w.Case__c, temp);
                    cBMap.put(w.Case__c, w.Case__r.IsUpdateWorkOrder__c);
                }

                /*
                    1、工程的保养、产品问题维修、仪器升级、仪器校准(工程)、移机 工单客户签名后工单完成、服务请求关闭；
                    2、工程的代理/自产安装工单需要客户签名且已上传安装报告后，工单完成服务请求关闭；
                    3、工程的非代理安装工单需要上传安装报告后，工单完成服务请求关闭；
                    4、应用的上试剂、临床推广、仪器培训、仪器校准、外出解决问题、技术巡回、授课培训、用户反馈、评价试验、软件安装培训工单，是否服务追踪不为空时，工单完成，是否回访不为空时，服务请求关闭
                */

                System.debug('+++'+cwMap);
                //经销商安装工单和正常安装工单完成逻辑一样
               // rtSet.remove('InstallationOrder');
               // woset.remove('InstallationOrder');
               // woset.remove('NonAgentInstallationOrder');
                for (Id ck : cwMap.keySet()) {
                        Boolean cando = true;
                      for (WorkOrder__c w:cwMap.get(ck) ) {

                        System.debug('***'+w.RecordType.DeveloperName + w.Status__c);
                            if(  rtSet.contains(w.Case__r.RecordType.DeveloperName) || woset.contains(w.RecordType.DeveloperName ) ){
                                cando =  w.Status__c == '完成'  ;
                            }else if((w.RecordType.DeveloperName != 'InstallationOrder' && 
                                         w.RecordType.DeveloperName != 'NonAgentInstallationOrder' && 
                                         w.RecordType.DeveloperName != 'ServiceOrder' && 
                                         w.RecordType.DeveloperName != 'MaintenanceOrder'
                                         &&  w.Visit__c == null)||( w.Status__c != '完成')) {

                            cando = false;
                            break;

                           

                      }


                   }
                    System.debug('***'+cando + ck );
                   //IsUpdateWorkOrder__c 改变是否更新工单  防止个案和服务请求更新 触发器循环
                    if(cando)clist.add(new Case(Id = ck, Status = '关闭',IsUpdateWorkOrder__c = !cBMap.get(ck)));
                    if(cando)lockList.addAll(cwMap.get(ck));
                } 
                /*     
                for(String ckey : mapCase.keySet()){
                    Boolean cando = true;
                    for(WorkOrder__c w : wList){
                        ///其他工单 回访不为空
                     /*   if(((w.RecordType.DeveloperName != 'InstallationOrder' && 
                            w.RecordType.DeveloperName != 'NonAgentInstallationOrder' && 
                            w.RecordType.DeveloperName != 'ServiceOrder' && 
                            w.RecordType.DeveloperName != 'MaintenanceOrder'
                             &&  w.Visit__c == null)
                              || 
                            ((w.RecordType.DeveloperName == 'InstallationOrder' ||
                            w.RecordType.DeveloperName == 'NonAgentInstallationOrder'
                              ) &&  (w.ReportNumber__c == null || w.ReportNumber__c == 0)) )&&

                               (w.Case__c == ckey && w.Status__c != '完成')) {

                           
                            cando = false;
                            break;

                        }                    

                    }
                    if(cando){
                         clist.add(new Case(Id = ckey, Status = '关闭',IsUpdateWorkOrder__c = !w.Case__r.AccountAddress__cIsUpdateWorkOrder__c));
                    }
                    
                }*/  
            }
            if(clist.size() > 0)update clist;
            try {
                if(!lockList.isEmpty())Approval.lock(lockList,false);
            }
            catch (Exception e) {
                
            }
            
             System.debug('+++'+clist);
            
        }
    }
}